package com.gitee.huanminabc.db_freedom.utils;

import cn.hutool.core.util.ReflectUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.gitee.huanminabc.db_freedom.wrapper.LambdaSQL;
import com.gitee.huanminabc.utils_common.base.SqlUtil;
import com.gitee.huanminabc.utils_common.string.StringUtil;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

@Component
public class SqlHelper {
    @Autowired
    private SqlSessionFactory sqlSessionFactory;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private TransactionTemplate transactionTemplate;

    public  void  execute(LambdaSQL lambdaSQL, String sql , Object... args) {
        jdbcTemplate.update(sql,args);
    }
    public   List<Map<String, Object>>  queryMaps(LambdaSQL lambdaSQL,String sql, Object... args){
        return  jdbcTemplate.queryForList(sql,args);
    }

    public  Map<String, Object>  queryMap(LambdaSQL lambdaSQL,String sql, Object... args) {
        return jdbcTemplate.queryForMap(sql,args);
    }

    public <T> T  queryOne(LambdaSQL lambdaSQL,String sql,Class<T> cl, Object... args) {
        return jdbcTemplate.query(sql,(rs)->{
            //获取实体 类中需要过滤的字段
            List<String> filter = new ArrayList<>();
            Field[] declaredFields = cl.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                TableField annotation = declaredField.getAnnotation(TableField.class);
                if (annotation != null && annotation.exist()) {
                    filter.add(declaredField.getName());
                }
            }
            return SqlUtil.resultSetToClass(rs, cl, filter.toArray(new String[0]));
        },args);
    }




    public  <T> List<T>  queryList(LambdaSQL lambdaSQL,String sql,Class<T> cl, Object... args) {
        return jdbcTemplate.query(sql,(rs)->{
            //获取实体 类中需要过滤的字段
            List<String> filter = new ArrayList<>();
            Field[] declaredFields = cl.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                TableField annotation = declaredField.getAnnotation(TableField.class);
                if (annotation != null && annotation.exist()) {
                    filter.add(declaredField.getName());
                }
            }
            return SqlUtil.resultSetToClassList(rs, cl, filter.toArray(new String[0]));
        },args);
    }

    public  List<Map<String, Object>> queryList(LambdaSQL lambdaSQL,String sql, Object... args) {
        return jdbcTemplate.queryForList(sql, args);
    }

    //这个sql不止是作为更新,也是可以作为插入的,多个sql即可
    //原理就是一个会话将多个sql一次性提交
    public  int[]  batchExecute(LambdaSQL[]  lambdaSQLS,  String... sql) {
      return   transactionTemplate.execute((status)-> jdbcTemplate.batchUpdate(sql));
    }

    //事物
    public  void  executeInTransaction(Function<SqlHelper,Void> function) {
        transactionTemplate.execute((status)-> function.apply(this));
    }


}
